package com.trailer.base.base

import android.content.Context
import android.os.Bundle
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import androidx.annotation.ArrayRes
import androidx.annotation.ColorRes
import androidx.annotation.IdRes
import androidx.annotation.StringRes
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.ViewModelProvider
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.hwangjr.rxbus.RxBus
import com.kingja.loadsir.callback.Callback.OnReloadListener
import com.kingja.loadsir.core.LoadService
import com.kingja.loadsir.core.LoadSir
import com.trello.rxlifecycle2.components.support.RxFragment
import com.trailer.base.BR
import com.trailer.base.R
import com.trailer.base.utils.Toasts
import com.trailer.base.utils.UiSwitch
import com.trailer.base.view.BView
import com.trailer.base.widget.TitleBar
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlin.coroutines.CoroutineContext

/**
 * Base Fragment
 *
 * @param <VM>
 * @param <B>
</B></VM> */
abstract class BFragment<VM : BViewModel<*>, B : ViewDataBinding> : RxFragment(), BView, OnReloadListener, TitleBar.DataSource, CoroutineScope {
    override var loadService: LoadService<*>? = null

    protected lateinit var vm: VM
    protected lateinit var binding: B
    private var swipeRefreshLayout: SwipeRefreshLayout? = null


    private val job = SupervisorJob()

    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + job


    override fun coroutine(): CoroutineScope {
        return this
    }

    private var isRefresh=false//没有数据时候点击不刷新

    protected var titleBar: TitleBar? = null

    private var page_status = 0
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        swipeRefreshLayout = view.findViewById(R.id.refresh_layout)
        if (swipeRefreshLayout != null) {
            setSwipeRefreshLayoutStyle()
        }
        var contentView: View? = null

        if (provideContainerId() != -1) {
            contentView = view.findViewById(provideContainerId())
        }
        if (contentView != null) {
            loadService = LoadSir.getDefault().register(contentView, this)
        }
        __before(savedInstanceState)
        initView(view)
        listeners()
        customizeEmptyView()
        init(savedInstanceState)
        isRefresh=true
        onReload(view)
    }

    open fun __before(savedInstanceState: Bundle?) {}
    override fun onDestroy() {
        super.onDestroy()
        unRegister()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        register()
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        binding = binding(inflater, container)
        binding.lifecycleOwner = this
        vm = ViewModelProvider(this).get(vmClass())
        vm.init()
        vm.attachView(this)
        binding.setVariable(BR.vm, vm)
        val view = binding.root as ViewGroup
        if (title() != null) {
            titleBar = TitleBar(context()!!, this)
            view.addView(titleBar, 0)
        }
        return view
    }

    override fun initView(view: View?) {}

    /**
     * 初始化
     *
     * @param savedInstanceState
     */
    protected open fun init(savedInstanceState: Bundle?) {}
    override fun customizeEmptyView() {}

    /**
     * 初始化Listeners
     */
    override fun listeners() {}
    protected abstract fun binding(inflater: LayoutInflater, container: ViewGroup?): B

    protected open fun vmClass(): Class<VM> {
        return BViewModel::class.java as Class<VM>
    }

    override fun context(): Context {
        return requireContext()
    }


    override fun onReload(v: View?) {
        if (needLogin() && user() == null) {
            toLogin()
            return
        }
        if(isRefresh) {
            vm.firstReq()
            isRefresh=false
        }
    }

    override fun finishActivity() {
        requireActivity().onBackPressed()
        requireActivity().overridePendingTransition(0, R.anim.acitivity_show_out_amination)
    }

    override fun finish() {
        requireActivity().onBackPressed()
    }

    override fun toast(msg: String?) {
        if (!TextUtils.isEmpty(msg)) {
            runOnUi(Runnable { Toasts.toast(context(), msg) })
        }
    }

    override fun toast(@StringRes msgID: Int) {
        toast(resources.getString(msgID))
    }

    override fun needLogin(): Boolean {
        return false
    }

    override fun processCodeOffline() {

    }

    override fun toLogin() {
        page_status = BActivity.TO_LOGIN
    }

    override fun onResume() {
        super.onResume()
        if (page_status == BActivity.TO_LOGIN) {
            onRefresh()
            page_status = 0
        }
    }

    override fun getEdtStr(editText: EditText?): String? {
        return editText!!.text.toString().trim { it <= ' ' }
    }

    override fun getStr(stringId: Int): String? {
        return getString(stringId)
    }

    override fun getStrArr(@ArrayRes strArrId: Int): Array<String?>? {
        return resources.getStringArray(strArrId)
    }

    override fun <T> single(clazz: Class<T>?) {
        UiSwitch.single(context(), clazz)
    }

    override fun <T> bundle(clazz: Class<T>?, bundle: Bundle?) {
        UiSwitch.bundle(context(), clazz, bundle)
    }

    override val isRxbus: Boolean
        get() = false

    override fun register() {
        if (isRxbus) {
            RxBus.get().register(this)
        }
    }

    override fun unRegister() {
        if (isRxbus) {
            RxBus.get().unregister(this)
        }
    }

    override fun view(): BView? {
        return this
    }

    override fun title(): String? {
        return ""
    }

    override fun backable(): Boolean {
        return true
    }

    @ColorRes
    override fun titleColor(): Int {
        return R.color.white
    }


    @ColorRes
    override fun rightTextColor(): Int {
        return R.color.white
    }


    override fun titleSize(): Int {
        return 17
    }

    fun setTitle(title: String?) {
        val activity = getActivity()
        activity?.runOnUiThread {
            if (titleBar != null) {
                if (!TextUtils.isEmpty(title)) {
                    titleBar!!.tv_title_bottom!!.visibility = View.VISIBLE
                    titleBar!!.tv_title_bottom!!.text = title
                } else {
                    titleBar!!.tv_title_bottom!!.visibility = View.GONE
                }
            }
        }
    }

    override fun runOnUi(runnable: Runnable?) {
        requireActivity().runOnUiThread(runnable)
    }


    override fun setStatusBar() {}
    override fun transluent(): Boolean = false

    override fun onRefresh() {
        isRefresh=true
        onReload(null)
    }

    override fun refreshing(refreshing: Boolean) {
        if (swipeRefreshLayout != null) {
            swipeRefreshLayout!!.isRefreshing = refreshing
        }
    }

    override val isNeedRefresh: Boolean
        get() = true

    fun setSwipeRefreshLayoutStyle() {
        /*下拉刷新设置*/
        if (swipeRefreshLayout != null) {
            swipeRefreshLayout!!.setColorSchemeResources(R.color.refresh_colorPrimary, R.color.refresh_colorAccent, R.color.refresh_colorPrimaryDark)
            swipeRefreshLayout!!.setOnRefreshListener { onRefresh() }
            swipeRefreshLayout!!.isEnabled = isNeedRefresh
        }
    }

    @IdRes
    override fun provideContainerId(): Int {
        return R.id.refresh_layout
    }

    override fun exitFromTopAnim(): Boolean {
        return false
    }
}
